package logic

import (
	"context"
	"errors"
	"strconv"
	"yim_server/utils/jwts"
	"yim_server/utils/open_login"
	"yim_server/yim_auth/auth_models"
	"yim_server/yim_user/user_rpc/userrpc"

	"yim_server/yim_auth/auth_api/internal/svc"
	"yim_server/yim_auth/auth_api/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type Open_loginLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewOpen_loginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Open_loginLogic {
	return &Open_loginLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *Open_loginLogic) Open_login(req *types.OpenLoginRequest) (resp *types.LoginResponse, err error) {

	type openInfo struct {
		Nickname     string
		FigureurlQQ2 string
		OpenId       string
	}

	var info openInfo

	switch req.Flag {
	case "qq":
		qqInfo, openError := open_login.NewQQLogin(req.Code, open_login.QQConfig{
			AppID:    l.svcCtx.Config.QQ.AppID,
			AppKey:   l.svcCtx.Config.QQ.AppKey,
			Redirect: l.svcCtx.Config.QQ.Redirect,
		})
		info = openInfo{
			Nickname:     qqInfo.Nickname,
			FigureurlQQ2: qqInfo.FigureurlQQ2,
			OpenId:       qqInfo.OpenId,
		}
		err = openError
	default:
		err = errors.New("不支持的三方登录")
	}
	if err != nil {
		logx.Error(err)
		return nil, errors.New("登录失败")
	}

	var user auth_models.UserModel
	err = l.svcCtx.DB.Take(&user, "open_id = ?", info.OpenId).Error
	if err != nil {
		// 用户不存在, 走注册逻辑
		req, err := l.svcCtx.UserRpc.UserCreate(l.ctx, &userrpc.UserCreateRequest{
			Nickname:       info.Nickname,
			Username:       info.Nickname,
			Password:       "",
			Role:           strconv.Itoa(2),
			Avatar:         info.FigureurlQQ2,
			OpenId:         info.OpenId,
			RegisterSource: "qq",
		})

		if err != nil {
			logx.Error(err)
			return nil, errors.New("登录失败")
		}

		user.Model.ID = uint(req.UserId)
		user.Role = 2
		user.Nickname = info.Nickname
		user.UserName = info.Nickname
	}

	// 登录逻辑
	token, err := jwts.GenToken(jwts.JwtPayLoad{
		UserID:   user.ID,
		Nickname: user.Nickname,
		Role:     user.Role,
	}, l.svcCtx.Config.Auth.AccessSecret, l.svcCtx.Config.Auth.AccessExpire)
	if err != nil {
		logx.Error(err)
		err = errors.New("服务内部错误")
		return nil, err
	}

	return &types.LoginResponse{
		Token: token,
	}, nil
}
